package com.ncucoder.soms.filter;

import com.ncucoder.soms.dto.ResponseDTO;
import com.ncucoder.soms.service.UserService;
import com.ncucoder.soms.util.JwtTokenUtils;
import com.ncucoder.soms.util.PropertyUtils;
import org.apache.shiro.web.filter.authc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * 基于JWT认证的过滤器
 *
 * @author <a href="https://www.ncucoder.com">hsowan</a>
 * @date 2019-07-08
 **/
public class JwtAuthFilter extends BasicHttpAuthenticationFilter {

    @Autowired
    private UserService userService;

    private Logger logger = LoggerFactory.getLogger(JwtAuthFilter.class);

    private String unauthorizedPage = PropertyUtils.properties.getProperty("shiro.unauthorized-url");

    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {

        return false;
    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {

        HttpServletRequest req = (HttpServletRequest) request;

        String optionsMethod = "OPTIONS";
        if (req.getMethod().equals(optionsMethod)) {
            return true;
        }

        HttpServletResponse resp = (HttpServletResponse) response;

        String token = req.getHeader(JwtTokenUtils.REQUEST_TOKEN_HEADER);
        logger.info(token);

        // 验证token是否有效以及去除token前缀
        String jwtToken = JwtTokenUtils.verify(token);
        if (jwtToken == null) {
            resp.setStatus(ResponseDTO.UNAUTHORIZED);
            return false;
        }
        String username = JwtTokenUtils.getUsername(jwtToken);

        // 通过jwtToken认证后, 将username保存到request中
        req.setAttribute("username", username);

        // 重新获取用户的角色
        String role = userService.getRoleByUsername(username);
        // 创建新的token
        String newToken = JwtTokenUtils.createToken(username, role);
        resp.setHeader(JwtTokenUtils.RESPONSE_TOKEN_HEADER, JwtTokenUtils.TOKEN_PREFIX + newToken);

        return true;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.setStatus(401);

        // false 验证失败不弹出登录框
        return false;
    }
}
